<?php

/**
 * Created by PhpStorm.
 * User: wenwb
 * Date: 2023/11/21
 * Time: 18:32
 */

namespace business\elasticsearch\services;

use business\elasticsearch\models\BigDataProjectLifeCycleModel;

class BigDataProjectLifeCycleService
{
    public function getList(
        $keyword,
        $id,
        $areaCode,
        $landUsage,
        $projectType,
        $fitmentFee,
        $takeLandDateStart,
        $takeLandDateEnd,
        $projectDateStart,
        $projectDateEnd,
        $buildDateStart,
        $buildDateEnd,
        $openDateStart,
        $openDateEnd,
        $completedDateStart,
        $completedDateEnd,
        $companyAreaCode,
        $companyType,
        $companyLabel,
        $industryCategory,
        $organizingCode,
        $projectPriceGtAvgLabel,
        $page,
        $pageSize
    )
    {
        $condition = $this->constructConditionGetList(
            $keyword,
            $id,
            $areaCode,
            $landUsage,
            $projectType,
            $fitmentFee,
            $takeLandDateStart,
            $takeLandDateEnd,
            $projectDateStart,
            $projectDateEnd,
            $buildDateStart,
            $buildDateEnd,
            $openDateStart,
            $openDateEnd,
            $completedDateStart,
            $completedDateEnd,
            $companyAreaCode,
            $companyType,
            $companyLabel,
            $industryCategory,
            $organizingCode,
            $projectPriceGtAvgLabel
        );
        if (empty($condition)) {
            return ['total' => 0, 'list' => []];
        }

        $query = BigDataProjectLifeCycleModel::find()->query($condition);
        //高亮处理
        $highlight = [
            'pre_tags' => ['<em class="_high">'],
            'post_tags' => ['</em>'],
            "fields" => [
                "title" => new \stdClass(),
                "developer_name" => new \stdClass(),
                "land_info_arr.title" => new \stdClass(),
                "approval_info_arr.title" => new \stdClass(),
                "building_info_arr.title" => new \stdClass(),
                "opening_info_arr.title" => new \stdClass(),
                "completion_info_arr.title" => new \stdClass(),
            ]
        ];
        $query->highlight($highlight);
        //$query->orderBy(['_score' => SORT_DESC, "order_date" => SORT_DESC, "_id" => SORT_DESC]);
        //20231207 不按得分排序，产品要求
        $query->orderBy(["order_date" => SORT_DESC, "_id" => SORT_DESC]);

        //分页处理
        $query->offset(($page - 1) * $pageSize)->limit($pageSize);
        $searchData = $query->createCommand()->search();

        $total = 0;
        $list = [];
        if (!empty($searchData)) {
            $data = $searchData["hits"]["hits"];
            $total = $searchData["hits"]["total"];
            foreach ($data as $dv) {
                $tmp = $dv['_source'];

                if (isset($dv['highlight']) && is_array($dv['highlight'])) {
                    foreach ($dv['highlight'] as $key => $value) {
                        $tmp[$key . 'HL'] = $value[0] ?? '';
                    }
                }
                $tmp['_score'] = $dv['_score'];

                //数据处理
                $tmp = $this->formatProject($tmp);
                $tmp['land_title_HL'] = $tmp['land_info_arr.titleHL'];
                $tmp['opening_title_HL'] = $tmp['opening_info_arr.titleHL'];
                //在建项目高亮：优先级：立项approval_info_arr>在建building_info_arr>竣工completion_info_arr
                $tmp['build_title_HL'] = !empty($tmp['approval_info_arr.titleHL']) ? $tmp['approval_info_arr.titleHL'] : !empty($tmp['building_info_arr.titleHL']) ? $tmp['building_info_arr.titleHL'] : $tmp['completion_info_arr.titleHL'];

                $list[] = $tmp;
            }
        }
        return ['total' => $total, 'list' => $list];

    }

    public function formatProject($data)
    {
        $return_params = [
            'id' => 'string',
            'title' => 'string',
            'project_stage_latest' => 'string',
            'developer_name' => 'string',
            'organizing_code' => 'string',
            'company_type' => 'string',
            'top_company_name' => 'string',
            'top_company_organizing_code' => 'string',
            'province' => 'string',
            'province_code' => 'string',
            'city' => 'string',
            'city_code' => 'string',
            'company_province' => 'string',
            'company_province_code' => 'string',
            'company_city' => 'string',
            'company_city_code' => 'string',
            'address' => 'string',
            'company_label_arr' => 'array',
            'industry_category_big' => 'string',
            'industry_category_middle' => 'string',
            'industry_category_small' => 'string',
            'land_usage_label_arr' => 'array',
            'project_type_label_arr' => 'array',
            'fitment_fee_label_arr' => 'array',
            'price_gt_avg_label' => 'string',
            'land_info_arr' => 'array',
            'land_info_cnt' => 'int',
            'approval_info_arr' => 'array',
            'approval_info_cnt' => 'int',
            'building_info_arr' => 'array',
            'building_info_cnt' => 'int',
            'opening_info_arr' => 'array',
            'opening_info_cnt' => 'int',
            'completion_info_arr' => 'array',
            'completion_info_cnt' => 'int',
            'bidding_info_arr' => 'array',
            'bidding_info_cnt' => 'int',
            'order_date' => 'string',
            'purchase_contact_cnt' => 'int',
            'coop_supplier_contact_cnt' => 'int',

            'titleHL' => 'string',
            'developer_nameHL' => 'string',
            'land_info_arr.titleHL' => 'string',
            'building_info_arr.titleHL' => 'string',
            'completion_info_arr.titleHL' => 'string',
            'approval_info_arr.titleHL' => 'string',
            'opening_info_arr.titleHL' => 'string',
            '_score' => 'int'
        ];

        $result = $data;
        foreach ($return_params as $rk => $rv) {
            $tmp = isset($data[$rk]) ? $data[$rk] : '';
            $tmp = $tmp === '1990-01-01 00:00:00' ? '' : $tmp;
            if ($rv == 'int') {
                $result[$rk] = (int)$tmp;
            } elseif ($rv == 'array') {
                $result[$rk] = empty($tmp) ? [] : $tmp;
            } else {
                $result[$rk] = $tmp;
            }
            //$result[$rk] = $rv == 'int' ? (int)$tmp : $tmp;
        }
        return $result;
    }

    public function constructConditionGetList(
        $keyword = '',
        $id = '',
        $areaCode = [],
        $landUsage = [],
        $projectType = [],
        $fitmentFee = [],
        $takeLandDateStart = '',
        $takeLandDateEnd = '',
        $projectDateStart = '',
        $projectDateEnd = '',
        $buildDateStart = '',
        $buildDateEnd = '',
        $openDateStart = '',
        $openDateEnd = '',
        $completedDateStart = '',
        $completedDateEnd = '',
        $companyAreaCode = [],
        $companyType = [],
        $companyLabel = [],
        $industryCategory = [],
        $organizingCode = [],
        $projectPriceGtAvgLabel = []
    )
    {
        $must = [];
        // 搜索条件
        // 关键词匹配项目名称、企业名称、关联（拿地、立项、开工、开盘、竣工）
        // and 公司类型 in companyType and 公司标签 in companyLabel and 公司地区 in companyArea
        // and 拿地日期 and 立项日期 and 开工日期 and 开工日期 and 竣工日期
        // and 土地用途 in landUsage and 工程用途 in projectType and 装修类型 in fitmentFee
        // and 项目地区 in area and 三级行业 in industryCategory
        //
        if ($keyword != "") {
            $keywordCondition = [];
            //项目名称
            $keywordCondition[] = [
                'match' => ['title.keyword' => ["query" => $keyword, "boost" => 200]]
            ];
            $slop = !empty(\Yii::$app->params['CommonDataDeveloperSlop']) ? \Yii::$app->params['CommonDataDeveloperSlop'] : 2;
            $keywordCondition[] = [
                'match_phrase' => ['title' => ["query" => $keyword, "boost" => 100, 'slop' => $slop]]
            ];
            //企业名称
            $keywordCondition[] = ['match_phrase' => ['developer_name' => ["query" => $keyword, "boost" => 200, 'slop' => $slop]]];
            //关联拿地节点名称
            $keywordCondition[] = ["nested" => ["path" => "land_info_arr", "query" => ["match_phrase" => ["land_info_arr.title" => ["query" => $keyword, "boost" => 100, 'slop' => $slop]]]]];
            //关联立项节点
            $keywordCondition[] = ["nested" => ["path" => "approval_info_arr", "query" => ["match_phrase" => ["approval_info_arr.title" => ["query" => $keyword, "boost" => 30, 'slop' => $slop]]]]];
            //关联开工节点
            $keywordCondition[] = ["nested" => ["path" => "building_info_arr", "query" => ["match_phrase" => ["building_info_arr.title" => ["query" => $keyword, "boost" => 30, 'slop' => $slop]]]]];
            //关联开盘节点
            $keywordCondition[] = ["nested" => ["path" => "opening_info_arr", "query" => ["match_phrase" => ["opening_info_arr.title" => ["query" => $keyword, "boost" => 100, 'slop' => $slop]]]]];
            //关联竣工节点
            $keywordCondition[] = ["nested" => ["path" => "completion_info_arr", "query" => ["match_phrase" => ["completion_info_arr.title" => ["query" => $keyword, "boost" => 30, 'slop' => $slop]]]]];

            $must[] = ["bool" => ["should" => $keywordCondition]];
        }

        if (!empty($areaCode)) {
            $must[] = ["bool" => ["should" => [["terms" => ["city_code" => $areaCode]], ["terms" => ["province_code" => $areaCode]]]]];
        }

        if (!empty($companyAreaCode)) {
            $must[] = ["bool" => ["should" => [["terms" => ["company_city_code" => $companyAreaCode]], ["terms" => ["company_province_code" => $companyAreaCode]]]]];
        }

        if (!empty($companyLabel)) {
            $must[] = ["nested" => ["path" => "company_label_arr", "query" => ["terms" => ["company_label_arr.label" => $companyLabel]]]];
        }

        if (!empty($id)) {
            $must[] = ["term" => ["id" => $id]];
        }

        if (!empty($companyType)) {
            $must[] = ["terms" => ["company_type" => $companyType]];
        }

        if (!empty($organizingCode)) {
            $must[] = ["terms" => ["organizing_code" => $organizingCode]];
        }

        if (!empty($industryCategory)) {
            $must[] = ["terms" => ["industry_category_small" => $industryCategory]];
        }

        if (!empty($landUsage)) {
            $must[] = ["nested" => ["path" => "land_usage_label_arr", "query" => ["terms" => ["land_usage_label_arr.label" => $landUsage]]]];
        }

        if (!empty($fitmentFee)) {
            $must[] = ["nested" => ["path" => "fitment_fee_label_arr", "query" => ["terms" => ["fitment_fee_label_arr.label" => $fitmentFee]]]];
        }

        if (!empty($projectType)) {
            $must[] = ["nested" => ["path" => "project_type_label_arr", "query" => ["terms" => ["project_type_label_arr.label" => $projectType]]]];
        }

        if (!empty($projectPriceGtAvgLabel)) {
            $must[] = ["terms" => ["project_price_gt_avg_label" => $projectPriceGtAvgLabel]];
        }

        //拿地日期
        $takeLandDateRange = [];
        if (!empty($takeLandDateStart)) {
            $takeLandDateRange['gte'] = date('Y-m-d', strtotime($takeLandDateStart)) . " 00:00:00";
        }
        if (!empty($takeLandDateEnd)) {
            $takeLandDateRange['lt'] = date('Y-m-d', strtotime($takeLandDateEnd)) . " 23:59:59";
        }
        if (!empty($takeLandDateRange)) {
            $must[] = ["nested" => ["path" => "land_info_arr", "query" => ['range' => ['land_info_arr.take_land_date' => $takeLandDateRange]]]];
        }

        //立项日期
        $projectDateRange = [];
        if (!empty($projectDateStart)) {
            $projectDateRange['gte'] = date('Y-m-d', strtotime($projectDateStart)) . " 00:00:00";
        }
        if (!empty($projectDateEnd)) {
            $projectDateRange['lt'] = date('Y-m-d', strtotime($projectDateEnd)) . " 23:59:59";
        }
        if (!empty($projectDateRange)) {
            $must[] = ["nested" => ["path" => "approval_info_arr", "query" => ['range' => ['approval_info_arr.project_date' => $projectDateRange]]]];
        }

        //开工日期
        $buildDateRange = [];
        if (!empty($buildDateStart)) {
            $buildDateRange['gte'] = date('Y-m-d', strtotime($buildDateStart)) . " 00:00:00";
        }
        if (!empty($buildDateEnd)) {
            $buildDateRange['lt'] = date('Y-m-d', strtotime($buildDateEnd)) . " 23:59:59";
        }
        if (!empty($buildDateRange)) {
            $must[] = ["nested" => ["path" => "building_info_arr", "query" => ['range' => ['building_info_arr.building_date' => $buildDateRange]]]];
        }

        //开盘日期
        $openDateRange = [];
        if (!empty($openDateStart)) {
            $openDateRange['gte'] = date('Y-m-d', strtotime($openDateStart)) . " 00:00:00";
        }
        if (!empty($openDateEnd)) {
            $openDateRange['lt'] = date('Y-m-d', strtotime($openDateEnd)) . " 23:59:59";
        }
        if (!empty($openDateRange)) {
            $must[] = ["nested" => ["path" => "opening_info_arr", "query" => ['range' => ['opening_info_arr.opening_date' => $openDateRange]]]];
        }

        //竣工日期
        $completedDateRange = [];
        if (!empty($completedDateStart)) {
            $completedDateRange['gte'] = date('Y-m-d', strtotime($completedDateStart)) . " 00:00:00";
        }
        if (!empty($completedDateEnd)) {
            $completedDateRange['lt'] = date('Y-m-d', strtotime($completedDateEnd)) . " 23:59:59";
        }
        if (!empty($completedDateRange)) {
            $must[] = ["nested" => ["path" => "completion_info_arr", "query" => ['range' => ['completion_info_arr.completed_date' => $completedDateRange]]]];
        }


        $query['function_score']['query']['bool']['must'] = $must;
        //权重排序
        /*$query['function_score']['functions'] = [
            ['script_score' => ['script' => "doc['business_score'].value"]],
        ];*/
        $query['function_score']['score_mode'] = 'sum';
        $query['function_score']['boost_mode'] = 'sum';

        return $query;
    }


    public function guessName($keyword, $pageSize): array
    {
        $condition = $this->constructConditionGetList($keyword);
        $query = BigDataProjectLifeCycleModel::find()
            ->query($condition);
        //高亮处理
        $highlight = [
            'pre_tags' => ['<em class="_high">'],
            'post_tags' => ['</em>'],
            "fields" => [
                "title" => new \stdClass(),
                //"developer_name" => new \stdClass(),
                "land_info_arr.title" => new \stdClass(),
                "approval_info_arr.title" => new \stdClass(),
                "building_info_arr.title" => new \stdClass(),
                "opening_info_arr.title" => new \stdClass(),
                "completion_info_arr.title" => new \stdClass(),
            ]
        ];
        $query->highlight($highlight);
        $query->orderBy(['_score' => SORT_DESC, "_id" => SORT_DESC]);

        //分页处理
        $query->limit($pageSize);
        $searchData = $query->createCommand()->search();
        //数据处理
        $result = [];
        if (!empty($searchData)) {
            $data = $searchData["hits"]["hits"];
            foreach ($data as $dv) {
                $tmp = $dv['_source'];
                if (empty($keyword)) {
                    //非联想
                    $item["titleHL"] = '';
                    $item["title"] = $tmp['title'];
                    $result[] = $item;
                } else {
                    //联想
                    if (isset($dv['highlight']) && is_array($dv['highlight'])) {
                        foreach ($dv['highlight'] as $key => $value) {
                            $tmp[$key . 'HL'] = $value[0] ?? '';
                        }
                    }


                    $hl = '';
                    $title = '';
                    $item = [];
                    if (!empty($tmp['titleHL'])) {
                        $hl = $tmp['titleHL'];
                        $title = $tmp['title'];
                        $item['type'] = "title";
                    } else if (!empty($tmp['land_info_arr.titleHL'])) {
                        $hl = $tmp['land_info_arr.titleHL'];
                        $title = str_replace("<em class=\"_high\">", "", str_replace("</em>", "", $tmp['land_info_arr.titleHL']));
                        $item['type'] = "land";
                    } else if (!empty($tmp['approval_info_arr.titleHL'])) {
                        $hl = $tmp['approval_info_arr.titleHL'];
                        $title = str_replace("<em class=\"_high\">", "", str_replace("</em>", "", $tmp['approval_info_arr.titleHL']));
                        $item['type'] = "approval_info";
                    } else if (!empty($tmp['building_info_arr.titleHL'])) {
                        $hl = $tmp['building_info_arr.titleHL'];
                        $title = str_replace("<em class=\"_high\">", "", str_replace("</em>", "", $tmp['building_info_arr.titleHL']));
                        $item['type'] = "building";
                    } else if (!empty($tmp['completion_info_arr.titleHL'])) {
                        $hl = $tmp['completion_info_arr.titleHL'];
                        $title = str_replace("<em class=\"_high\">", "", str_replace("</em>", "", $tmp['completion_info_arr.titleHL']));
                        $item['type'] = "completion_info";
                    } else if (!empty($tmp['opening_info_arr.titleHL'])) {
                        $hl = $tmp['opening_info_arr.titleHL'];
                        $title = str_replace("<em class=\"_high\">", "", str_replace("</em>", "", $tmp['opening_info_arr.titleHL']));
                        $item['type'] = "'opening_info";
                    }
                    $item["titleHL"] = $hl;
                    $item["title"] = $title;
                    $result[] = $item;
                }

            }
        }
        return $result;
    }
}
